home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_499 / diglib / diglib.lzh / source / PURJOY.for < prev    next >
Text File  |  1991-05-22  |  33KB  |  992 lines

  1.  
  2.         SUBROUTINE PURJOY(Z,IZDIM1,IZ,KX,KY,CAMLOC,XYLIM,
  3.      1   XLAB,YLAB,ZLAB,CSIZE,MARPLT)
  4. C
  5. CPurpose:   This subroutine will plot a function Z=F(X,Y) as a lined surface.
  6. C       The function must be defined on a regular grid.   This routine will
  7. C       optionally remove hidden lines.
  8. C
  9. CArguments:
  10. C
  11. C  Input
  12. C
  13. C       Z               * Type: real array.
  14. C                       * The function values: Z(I,J)=F(Xi,Yj), where
  15. C                               Xi = XMIN + (i-1)*(XMAX-XMIN)/(KX-1)
  16. C                               Yj = YMIN + (j-1)*(YMAX-YMIN)/(KY-1)
  17. C
  18. C       IZDIM1          * Type: integer constant or variable.
  19. C                       * The first dimension of the Z array - not
  20. C                               necessarily the number of X values.
  21. C
  22. C       IZ              * Type: byte array.
  23. C                       * A working array of bytes dimensioned atleast
  24. C                               KX*KY long.
  25. C
  26. C       KX              * Type: integer constant or variable.
  27. C                       * The number of X values in the Z array.
  28. C                               KX <= IZDIM1 ofcourse.
  29. C
  30. C       KY              * Type: integer constant or variable.
  31. C                       * The number of Y values in the Z array.
  32. C
  33. C       CAMLOC          * Type: real array.
  34. C                       * The relative location of the viewer in space.
  35. C                               The viewer always faces toward the center
  36. C                               of the surface.
  37. C                               CAMLOC(1) = distance from surface in units
  38. C                                the same as those of Z.
  39. C                               CAMLOC(2) = angle between the viewer and the
  40. C                                X axis in degrees.   Usually, multiples of
  41. C                                30 or 45 degrees are best.
  42. C                               CAMLOC(3) = angle between the viewer and the
  43. C                                XY plane located at Z=(ZMIN+ZMAX)/2 in
  44. C                                degrees.   Thus 90 degrees is directly above
  45. C                                the surface - an unexciting picture!   Usual
  46. C                                the angle is selected near 45 degrees.
  47. C
  48. C       XYLIM           * Type: real two dimensional array dimensioned (2,6).
  49. C                       * General parameters:
  50. C                               XYLIM(1,1) = XMIN ==> the minimum value of X.
  51. C                               XYLIM(2,1) = XMAX ==> the maximum value of X.
  52. C                               XYLIM(1,2) = YMIN ==> the minimum value of Y.
  53. C                               XYLIM(2,2) = YMAX ==> the maximum value of Y.
  54. C                                Note: Z(I,J) = F(Xi,Yj) where:
  55. C                                  Xi = XMIN + (i-1)*(XMAX-XMIN)/(KX-1)
  56. C                                  Yj = YMIN + (j-1)*(YMAX-YMIN)/(KY-1)
  57. C                               XYLIM(1,3) = ZMIN ==> the minimum value of Z.
  58. C                               XYLIM(2,3) = ZMAX ==> the maximum value of Z.
  59. C                                These Z values define the range of Z values
  60. C                                to fit on the screen.   It is strongly
  61. C                                advised that ZMIN and ZMAX bound Z(I,J).
  62. C                               XYLIM(1,4) = X/Z axis length ratio.   If this
  63. C                                parameter is 0, then X and Z are assumed to
  64. C                                have the same units, so their relative
  65. C                                lengths will be in proportion to their
  66. C                                ranges.   If this parameter is nonzero, then
  67. C                                the X axis will be XYLIM(1,4) times as long
  68. C                                as the Z axis.
  69. C                               XYLIM(2,4) = Y/Z axis length ratio.   Same as
  70. C                                XYLIM(1,4), but for Y axis.
  71. C                               XYLIM(1,5) = plot width in virtual coordinate
  72. C                               XYLIM(2,5) = plot height in virtual coord.
  73. C                                Note: The plot is expanded/contracted until
  74. C                                it all fits within the box defined by
  75. C                                XYLIM(1,5) and XYLIM(2,5).
  76. C                               XYLIM(1,6) = virtual X coord. of the lower
  77. C                                left corner of the plot box.
  78. C                               XYLIM(2,6) = virtual Y coord. of the lower
  79. C                                left corner of the box.
  80. C
  81. C       XLAB            * Type: string constant or variable.
  82. C                       * The X axis lable.
  83. C
  84. C       YLAB            * Type: string constant or variable.
  85. C                       * The Y axis lable.
  86. C
  87. C       ZLAB            * Type: string constant or variable.
  88. C                       * The Z axis lable.
  89. C
  90. C       CSIZE           * Type: real constant or variable.
  91. C                       * The character size in virtual coord. for the tick
  92. C                               mark lables and the axis lables.
  93. C
  94. C       MARPLT          * Type: integer constant or variable.
  95. C                       * Hidden line flag:
  96. C                         0 ==> draw all lines, hidden or not.
  97. C                         1 ==> suppress all lines hidden by the surface, but
  98. C                               display both the top and bottom of the surfac
  99. C                         3 ==> suppress all lines hidden by the surface, and
  100. C                               all lines showing the bottom of the surface.
  101. C                         Add 4 to MARPLT if you do not want the axes nor the
  102. C                          ticks labled.   This is useful on small plots.
  103. C
  104.     IMPLICIT NONE
  105.     REAL*4 ZMIN,ZMAX,AXISR(2),CAMXYZ(3)
  106.     REAL*4CAMWKG(6),XORG(3),GX(3),FX(2),CENTER(2),AMTX(3,3)
  107.     REAL*4 PLTORG(2),U,V,W
  108.  
  109.     INCLUDE DIGLIB$KOM:GCDCHR.PRM
  110.     INCLUDE DIGLIB$KOM:PLTCLP.PRM
  111.  
  112.         REAL*4 Z(IZDIM1,KY), CAMLOC(3), XYLIM(2,6)
  113.         CHARACTER*1 IZ(KX,KY), XLAB(2), YLAB(2), ZLAB(2)
  114.         EXTERNAL LEN
  115. C
  116. C       COMMON STORAGE DESCRIPTOR
  117.  
  118.     REAL*4 PLOTX,PLOTY,MX,NY,FMX,FNY,ZORG,PQLMT,FOCALL
  119.     INTEGER KSCALE,LEN
  120.         COMMON/COMDP/ZMIN,ZMAX,AXISR,PLOTX,
  121.      1   PLOTY,PLTORG,CAMXYZ,MX,NY,FMX,FNY,CAMWKG,XORG,
  122.      2   GX,FX,KSCALE,ZORG,CENTER,PQLMT,
  123.      3   AMTX,FOCALL
  124.         INTEGER LIMIT(2)
  125.     REAL*4 FLIM(2)
  126.         EQUIVALENCE(U,CAMXYZ(1)),(V,CAMXYZ(2)),(W,CAMXYZ(3)),
  127.      1   (MX,LIMIT(1)),(FMX,FLIM(1))
  128. C       END CDE
  129. C
  130.         LOGICAL LSOLID
  131.         COMMON /COMDP1/ LSOLID
  132. C
  133. C       LOCAL CDE
  134.         REAL*4 XMINA(2,2)
  135.         LOGICAL LLABLE
  136.         EQUIVALENCE(XMIN,XMINA(1,1))
  137.  
  138.     INCLUDE DIGLIB$KOM:PLTPRM.PRM
  139.  
  140.     REAL*4 VX,VY,VOLDX,VOLDY,RAD,PHI,THETA,XA,XB,YA,YB,DX,DY
  141.     REAL*4 XZ,YZ,FRX,BKX,FRY,BKY,TEMP,ETA,VXT,VYT
  142.     INTEGER IF,IB,JF,JB,I,J,IERR,K,L,IVIS
  143.         COMMON /DBASE/VX,VY,VOLDX,VOLDY
  144. C
  145. C       TYPE 800, KX,KY,XYLIM
  146. C800    FORMAT(' DEBUG-- KX,KY = ',2I5/' XYLIM='6(/1X,2E14.6))
  147. C       PICK UP XY LIMITS, BOX SIZES, ETC.
  148.         DO 9 J=1,2
  149.         XMINA(1,J) = XYLIM(1,J)
  150. 9       XMINA(2,J) = XYLIM(2,J)
  151.         ZMIN = XYLIM(1,3)
  152.         ZMAX = XYLIM(2,3)
  153.         PLOTX = XYLIM(1,5)
  154.         PLOTY = XYLIM(2,5)
  155.         AXISR(1) = XYLIM(1,4)
  156.         AXISR(2) = XYLIM(2,4)
  157.         PLTORG(1) = XYLIM(1,6)
  158.         PLTORG(2) = XYLIM(2,6)
  159. C
  160. C       NOW SET UP LIMITS IF AXIS RATIOS ARE REQUESTED
  161. C
  162.         IF (AXISR(1) .EQ. 0.0) GO TO 260
  163.         DO 255 I=1,2
  164. 255     XMINA(1,I)=AXISR(I)*ZMIN
  165. 260     IF (AXISR(2) .EQ. 0.0) GO TO 266
  166.         DO 265 I=1,2
  167. 265     XMINA(2,I)=AXISR(I)*ZMAX
  168. C       SET TOLERANCE FOR VISIBLE TESTS = HALF PLOTTER STEP SIZE
  169. 266     PQLMT = AMIN1(0.5/XRES,0.5/YRES)
  170. C       TYPE 504, XMINA
  171. C
  172. C       CONVERT R, PHI, THETA TO DX, DY, DZ
  173. C
  174.         RAD = 3.14159/180.0
  175.         PHI = CAMLOC(2)*RAD
  176.         THETA = CAMLOC(3)*RAD
  177.         CAMWKG(1)=CAMLOC(1)*COS(PHI)*COS(THETA)
  178.         CAMWKG(2)=CAMLOC(1)*SIN(PHI)*COS(THETA)
  179.         CAMWKG(3)=CAMLOC(1)*SIN(THETA)
  180. C       PICK UP CAMERA DATA
  181.         DO 3 J=1,2
  182.         CAMWKG(J+3)=(XMINA(1,J)+XMINA(2,J))/2.0
  183. 3       CAMWKG(J)=CAMWKG(J+3)+CAMWKG(J)
  184.         CAMWKG(6)=ZMIN+ZMAX/2.0
  185.         CAMWKG(3)=CAMWKG(6)+CAMWKG(3)
  186.         CALL CAMROT
  187.         MX=KX
  188.         FMX=FLOAT(KX)
  189.         NY=KY
  190.         FNY=FLOAT(NY)
  191. C       OPTION FOR SCALING Z
  192. C       SCALE FACTORS TO CONVERT USER VALUES TO INDICES
  193.         GX(1) = (XMAX-XMIN)/(FMX-1.0)
  194.         GX(2) = (YMAX-YMIN)/(FNY-1.0)
  195. C
  196. C       FIND Z SCALE FACTOR
  197. C
  198.         GX(3)=1.0
  199.         ZORG=0.0
  200. C
  201. C       FIND SCALE FACTORS FOR PLOT
  202. C
  203.         CYSIZE = CSIZE
  204.         CXSIZE = 9.0*CYSIZE/8.0
  205.         XA=1.0E30
  206.         XB=-1.0E30
  207.         YA=1.0E30
  208.         YB=-1.0E30
  209.         IF (CAMWKG(3) .LT. CAMWKG(6)) GO TO 16
  210.         DX=FLOAT(MX-1)/20.0
  211.         DY=FLOAT(NY-1)/20.0
  212.         IF=MX
  213.         XZ = XMAX
  214.         IB=1
  215.         JF=NY
  216.         YZ = YMIN
  217.         JB=1
  218.         IF (CAMWKG(1) .GE. CAMWKG(4)) GO TO 120
  219.         IF=1
  220.         XZ = XMIN
  221.         IB=MX
  222.         DX=-DX
  223. 120     IF (CAMWKG(2) .GE. CAMWKG(5)) GO TO 130
  224.         JF=1
  225.         YZ = YMAX
  226.         JB=NY
  227.         DY=-DY
  228. 130     FRX=IF
  229.         BKX=IB
  230.         FRY=JF
  231.         BKY=JB
  232.         VX = XMIN + (FRX-1.0)*GX(1) - CAMWKG(1)
  233.         VY = YMIN + (BKY-1.0-DY)*GX(2) - CAMWKG(2)
  234.         CALL EXTRMA(VX,VY,ZMAX-CAMWKG(3),XA,XB,YA,YB,IERR)
  235.         IF (IERR .NE. 0) GO TO 50
  236.         TEMP = ZMIN - CAMWKG(3)
  237.         CALL EXTRMA(VX,VY,TEMP,XA,XB,YA,YB,IERR)
  238.         IF (IERR .NE. 0) GO TO 50
  239.         VY = YMIN + (FRY-1.0+DY)*GX(2) - CAMWKG(2)
  240.         CALL EXTRMA(VX,VY,TEMP,XA,XB,YA,YB,IERR)
  241.         IF (IERR .NE. 0) GO TO 50
  242.         CALL EXTRMA(XMIN+(BKX-1.0)*GX(1)-CAMWKG(1),VY,TEMP,
  243.      1   XA,XB,YA,YB,IERR)
  244.         IF (IERR .NE. 0) GO TO 50
  245.         VX = VX + DX*GX(1)
  246.         CALL EXTRMA(VX,YMIN+(BKY-1.0)*GX(2)-CAMWKG(2),TEMP,
  247.      1   XA,XB,YA,YB,IERR)
  248.         IF (IERR .NE. 0) GO TO 50
  249.         CALL EXTRMA(VX,VY-DY*GX(2),TEMP,XA,XB,YA,YB,IERR)
  250.         IF (IERR .NE. 0) GO TO 50
  251. 16      DO 20 J=1,NY
  252.         VY = YMIN + (J-1)*GX(2) - CAMWKG(2)
  253.         DO 20 I=1,MX
  254.         VX = XMIN + (I-1)*GX(1) - CAMWKG(1)
  255.         CALL EXTRMA(VX,VY,Z(I,J)-CAMWKG(3),XA,XB,YA,YB,IERR)
  256.         IF (IERR .NE. 0) GO TO 50
  257. 20      CONTINUE
  258. C
  259. C       SCALE X AND Y RANGES TO FIT ON PLOT
  260. C
  261.         TEMP = 12.5*CXSIZE
  262.         LLABLE = .TRUE.
  263.         IF ((MARPLT.AND.4) .NE. 0) LLABLE = .FALSE.
  264.         IF (.NOT. LLABLE) TEMP = 0.0
  265.         FX(1) = (PLOTX-TEMP)/(XB-XA)
  266.         TEMP = 2.0*CYSIZE
  267.         IF (.NOT. LLABLE) TEMP = 0.0
  268.         FX(2) = (PLOTY-TEMP)/(YB-YA)
  269. C       CHOOSE MINIMUM FOCAL LENGTH OF THE TWO
  270.         FOCALL = AMIN1(FX(1),FX(2))
  271. C       SET X,Y ORIGINS (BEFORE SCALING TO FOCAL LGTH)
  272.         XORG(1) = XA
  273.         XORG(2) = YA
  274. C       SIZES IN X,Y (NOT INCLUDING OUT-OF-BOX POIINTS THAT GET IN PIC)
  275.         XB = (XB-XA)*FOCALL
  276.         YB = (YB-YA)*FOCALL
  277. C       CENTER FOR NOW, BUT LATER MAKE OPTIONAL
  278.         CENTER(1) = (PLOTX-XB)/2.0
  279.         CENTER(2) = (PLOTY-YB)/2.0
  280. C       TYPE 602, FX,XB,YB,PLOTX,PLOTY,CENTER
  281. C
  282. C       CAMERA LOCATION EXPRESSED AS XY INDICES
  283.         U = 1.0+(FMX-1.0)*(CAMWKG(1)-XMIN)/(XMAX-XMIN)
  284.         V = 1.0+(FNY-1.0)*(CAMWKG(2)-YMIN)/(YMAX-YMIN)
  285. C       FOR VISIBILITY CHECKING, SCALE CAMERA Z COORDINATE OPPOSITE TO THE
  286. C       WAY Z WILL BE SCALED FOR PLOTTING - RATHER THAN SCALING ALL THE
  287. C       Z-S ON THE SURFACE WHEN CHECKING.
  288.         W = (CAMWKG(3)-ZORG)/GX(3)
  289. C       CALCULATE VISIBILITIES
  290. C
  291. C       IF LSB OF MARPLT IS SET, SUPRESS ALL HIDDEN LINES
  292.         IF ((MARPLT.AND.1) .NE. 0) GO TO 7
  293.         DO 8 K = 1,NY
  294.         DO 8 J = 1,MX
  295. 8       IZ(J,K)=0
  296.         GO TO 40
  297. 7       LSOLID = .FALSE.
  298.         IF ((MARPLT.AND.2) .NE. 0) LSOLID = .TRUE.
  299.         DO 1 K = 1,NY
  300.         ETA = FLOAT(K)
  301.         DO 1 J =1,MX
  302.          L = IVIS(FLOAT(J),ETA,Z(J,K),Z,IZDIM1)+1
  303. 1       IZ(J,K)=L
  304. C
  305. C       NOW PLOT
  306. 40      CALL DRAW3D(Z,IZDIM1,IZ,KX)
  307.         IF (CAMWKG(3) .LT. CAMWKG(6)) GO TO 45
  308.         CALL GSSETC(CYSIZE,0.0)
  309.         CALL XYPRM(FRX,BKY,ZMAX,0)
  310.         VOLDX=VX
  311.         VOLDY=VY
  312.         VXT=VX
  313.         VYT=VY
  314.         CALL XYPRM(FRX,BKY-DY,ZMAX,1)
  315.         IF (LLABLE) CALL TICKL(ZMAX,-0.5)
  316.         CALL GSMOVE(VXT,VYT)
  317.         CALL XYPRM(FRX,BKY,ZMIN,1)
  318.         VOLDX=VX
  319.         VOLDY=VY
  320.         CALL XYPRM(FRX,BKY-DY,ZMIN,1)
  321.         IF (.NOT. LLABLE) GO TO 140
  322.         CALL TICKL(ZMIN,0.25)
  323.         TEMP = AMAX1(VOLDX,VXT)+1.5*CYSIZE
  324.         IF (VX .LT. VOLDX) TEMP = AMIN1(VOLDX,VXT)-0.5*CYSIZE
  325.         CALL GSMOVE(TEMP,(VOLDY+VYT-CXSIZE*LEN(ZLAB))/2.0)
  326.         CALL GSSETC(CYSIZE,90.0)
  327.         CALL GSPSTR(ZLAB)
  328.         CALL GSSETC(CYSIZE,0.0)
  329. 140     CALL GSMOVE(VOLDX,VOLDY)
  330.         CALL XYPRM(FRX+DX,BKY,ZMIN,1)
  331.         IF (LLABLE) CALL TICKL(XYLIM(1+JB/NY,2),-0.5)
  332.         CALL GSMOVE(VOLDX,VOLDY)
  333.         CALL XYPRM(FRX,FRY+DY,ZMIN,1)
  334.         IF (.NOT. LLABLE) GO TO 150
  335.         CALL TICKL(XYLIM(1+IF/MX,1),-0.5)
  336.         TEMP = CXSIZE*(LEN(YLAB)+0.25)
  337.         IF (VX .LT. VOLDX) TEMP = -0.25*CXSIZE
  338.         CALL GSMOVE((VX+VOLDX)/2.0-TEMP,(VY+VOLDY)/2.0-CYSIZE)
  339.         CALL GSPSTR(YLAB)
  340. 150     CALL XYPRM(FRX,FRY,Z(IF,JF),-1)
  341.         CALL GSMOVE(VX,VY)
  342.         CALL XYPRM(FRX,FRY,ZMIN,1)
  343.         VOLDX=VX
  344.         VOLDY=VY
  345.         CALL XYPRM(FRX+DX,FRY,ZMIN,1)
  346.         IF (LLABLE) CALL TICKL(XYLIM(1+JF/NY,2),-0.5)
  347.         CALL GSMOVE(VOLDX,VOLDY)
  348.         CALL XYPRM(BKX,FRY,ZMIN,1)
  349.         IF (.NOT. LLABLE) GO TO 160
  350.         TEMP = CXSIZE*(LEN(XLAB)+0.25)
  351.         IF (VX .GT. VOLDX) TEMP = -0.25*CXSIZE
  352.         CALL GSMOVE((VX+VOLDX)/2.0-TEMP,(VY+VOLDY)/2.0-CYSIZE)
  353.         CALL GSPSTR(XLAB)
  354. 160     VOLDX=VX
  355.         VOLDY=VY
  356.         CALL GSMOVE(VX,VY)
  357.         CALL XYPRM(BKX,FRY+DY,ZMIN,1)
  358.         IF (LLABLE) CALL TICKL(XYLIM(1+IB/MX,1),-0.5)
  359.         CALL GSMOVE(VOLDX,VOLDY)
  360.         CALL XYPRM(BKX,FRY,Z(IB,JF),1)
  361. 45      RETURN
  362. C
  363. C       POINT ON THE SURFACE IS BEHIND THE CAMERA. QUIT.
  364. C
  365.   50    WRITE(9,603)
  366.         RETURN
  367. C
  368. C       Z IS A FLAT PLANE, DO NOT DRAW (FOR NOW)
  369. C
  370.   60    WRITE(9,604)
  371.         RETURN
  372. C
  373. C 503 FORMAT(' Z MULTIPLIER',E15.6,', Z ORIGIN SHIFT',E15.6)
  374. C504    FORMAT('0X LIMITS',2F10.3/' Y LIMITS',2F10.3/' Z LIMITS',2F10.3/
  375. C       1' Z CUTOFF',2E15.6/
  376. C       2                 ' PLOT SIZE',2F10.3/' PLOT ORIGIN',2F10.3)
  377. C 602 FORMAT('0FOCAL LENGTHS TO FILL X,Y PLOTTER SPACE',2E15.6,
  378. C    1 ', LESSER VALUE CHOSEN'/'0PICTURE SIZE IN X,Y =',2F9.3,
  379. C    2 ', REQUESTED SIZES',2F9.3/' CENTERS = ',2G14.7)
  380.   603 FORMAT('PART OF SURFACE IS BEHIND THE CAMERA, UNABLE TO PLOT. SOR
  381.      1RY.')
  382.   604 FORMAT('FUNCTION IS LEVEL PLANE, NO USE PLOTTING IT')
  383.         END
  384.         SUBROUTINE EXTRMA(XV,YV,ZV,XA,XB,YA,YB,IERR)
  385.     IMPLICIT NONE
  386. C
  387. C       COMMON STORAGE DESCRIPTOR
  388.     INCLUDE DIGLIB$KOM:PLTCLP.PRM
  389.  
  390.     REAL*4 ZMIN,ZMAX,AXISR(2),CAMXYZ(3)
  391.     REAL*4CAMWKG(6),XORG(3),GX(3),FX(2),CENTER(2),AMTX(3,3)
  392.     REAL*4 PLTORG(2),U,V,W
  393.     REAL*4 PLOTX,PLOTY,MX,NY,FMX,FNY,ZORG,PQLMT,FOCALL
  394.     INTEGER KSCALE
  395.         COMMON/COMDP/ZMIN,ZMAX,AXISR,PLOTX,
  396.      1   PLOTY,PLTORG,CAMXYZ,MX,NY,FMX,FNY,CAMWKG,XORG,
  397.      2   GX,FX,KSCALE,ZORG,CENTER,PQLMT,
  398.      3   AMTX,FOCALL
  399.         REAL*4 FLIM(2)
  400.     INTEGER LIMIT(2)
  401.         EQUIVALENCE(U,CAMXYZ(1)),(V,CAMXYZ(2)),(W,CAMXYZ(3)),
  402.      1   (MX,LIMIT(1)),(FMX,FLIM(1))
  403. C       END CDE
  404. C
  405.         REAL*4 XS(3), XC(3)
  406. C
  407. C
  408.         XS(1) = XV
  409.         XS(2) = YV
  410.         XS(3) = ZV
  411.         CALL ROTATE(XS,AMTX,XC)
  412. C       QUIT IF POINT IS BEHIND CAMERA
  413.         IF(XC(3).LE.0.0) GO TO 50
  414.         XC(1) = XC(1)/XC(3)
  415.         XC(2) = XC(2)/XC(3)
  416.         XA = AMIN1(XA,XC(1))
  417.         XB = AMAX1(XB,XC(1))
  418.         YA = AMIN1(YA,XC(2))
  419.         YB = AMAX1(YB,XC(2))
  420.         IERR = 0
  421.         RETURN
  422. 50      IERR = -1
  423.         RETURN
  424.         END
  425.         SUBROUTINE XYPRM(X,Y,ZETA,ILINE)
  426.     IMPLICIT NONE
  427. C
  428. C       COMMON STORAGE DESCRIPTOR
  429.     INCLUDE DIGLIB$KOM:PLTCLP.PRM
  430.     INCLUDE DIGLIB$KOM:PLTPRM.PRM
  431.  
  432.     REAL*4 ZMIN,ZMAX,AXISR(2),CAMXYZ(3)
  433.     REAL*4CAMWKG(6),XORG(3),GX(3),FX(2),CENTER(2),AMTX(3,3)
  434.     REAL*4 PLTORG(2),U,V,W
  435.     REAL*4 PLOTX,PLOTY,MX,NY,FMX,FNY,ZORG,PQLMT,FOCALL
  436.     INTEGER KSCALE
  437.         COMMON/COMDP/ZMIN,ZMAX,AXISR,PLOTX,
  438.      1   PLOTY,PLTORG,CAMXYZ,MX,NY,FMX,FNY,CAMWKG,XORG,
  439.      2   GX,FX,KSCALE,ZORG,CENTER,PQLMT,
  440.      3   AMTX,FOCALL
  441.         INTEGER LIMIT(2)
  442.     REAL*4 FLIM(2)
  443.         EQUIVALENCE(U,CAMXYZ(1)),(V,CAMXYZ(2)),(W,CAMXYZ(3)),
  444.      1   (MX,LIMIT(1)),(FMX,FLIM(1))
  445. C       END CDE
  446. C
  447.     REAL*4 VX,VY,VOLDX,VOLDY
  448.         COMMON /DBASE/VX,VY,VOLDX,VOLDY
  449.         REAL*4 XS(3),XC(3)
  450.         XS(1)=XMIN+(X-1.0)*GX(1)-CAMWKG(1)
  451.         XS(2)=YMIN+(Y-1.0)*GX(2)-CAMWKG(2)
  452.         XS(3)=ZORG + ZETA*GX(3)-CAMWKG(3)
  453.         CALL ROTATE(XS,AMTX,XC)
  454.         VX=(XC(1)/XC(3)-XORG(1))*FOCALL+PLTORG(1)+CENTER(1)
  455.         VY=(XC(2)/XC(3)-XORG(2))*FOCALL+PLTORG(2)+CENTER(2)
  456.         IF (ILINE) 30, 20, 10
  457. 10      CALL GSDRAW(VX,VY)
  458.         GO TO 30
  459. 20      CALL GSMOVE(VX,VY)
  460. 30      RETURN
  461.         END
  462.         SUBROUTINE TICKL(ANUM,UP)
  463.     IMPLICIT NONE
  464.     INCLUDE DIGLIB$KOM:PLTPRM.PRM
  465.     REAL*4 VX,VY,VOLDX,VOLDY,TEMP
  466.     INTEGER IS
  467.         COMMON /DBASE/VX,VY,VOLDX,VOLDY
  468.         CHARACTER*8 TEMP1,TEMP2
  469.         CHARACTER*1 NUMBR(8)
  470.         EQUIVALENCE (NUMBR(1),TEMP2)
  471. C       ENCODE(6,10,NUMBR) ANUM
  472. C10     FORMAT(F6.2)
  473.         WRITE(TEMP2,451) ANUM
  474. C       READ(TEMP1,452) TEMP2
  475. 451     FORMAT(F6.2)
  476. 452     FORMAT(A8)
  477.         DO 20 IS=1,6
  478.         IF(NUMBR(IS) .NE. 32) GO TO 30
  479. 20      CONTINUE
  480. 30      NUMBR(7)=0
  481.         TEMP = CXSIZE*((7-IS)+0.25)
  482.         IF (VX .GT. VOLDX) TEMP = -0.25*CXSIZE
  483.         CALL GSMOVE(VX-TEMP,VY+UP*CYSIZE)
  484.         CALL GSPSTR(NUMBR(IS))
  485.         RETURN
  486.         END
  487.         SUBROUTINE CAMROT
  488.     IMPLICIT NONE
  489. C       MAKE UP CAMERA ROTATION MATRIX
  490. C
  491. C       ROTATION IS DONE SO THAT Z PRIME AXIS IS DIRECTED FROM THE
  492. C       CAMERA TO THE AIMING POINT.   NOTE ALSO THAT THE PRIMED
  493. C       COORDINATE SYSTEM IS LEFT-HANDED IF EPSLON=-1.
  494. C       THIS IS SO THAT THE PICTURE COMES OUT RIGHT WHEN PROJECTED
  495. C       ON THE PRIMED COORDINATE SYSTEM.
  496. C
  497. C       COMMON STORAGE DESCRIPTOR
  498.     INCLUDE DIGLIB$KOM:PLTCLP.PRM
  499.     REAL*4 ZMIN,ZMAX,AXISR(2),CAMXYZ(3)
  500.     REAL*4CAMWKG(6),XORG(3),GX(3),FX(2),CENTER(2),AMTX(3,3)
  501.     REAL*4 PLTORG(2),U,V,W
  502.     REAL*4 PLOTX,PLOTY,MX,NY,FMX,FNY,ZORG,PQLMT,FOCALL
  503.     INTEGER KSCALE
  504.         COMMON/COMDP/ZMIN,ZMAX,AXISR,PLOTX,
  505.      1   PLOTY,PLTORG,CAMXYZ,MX,NY,FMX,FNY,CAMWKG,XORG,
  506.      2   GX,FX,KSCALE,ZORG,CENTER,PQLMT,
  507.      3   AMTX,FOCALL
  508.         INTEGER LIMIT(2),J
  509.     REAL*4 FLIM(2),EPSLON,S,SIGMA
  510.         EQUIVALENCE(U,CAMXYZ(1)),(V,CAMXYZ(2)),(W,CAMXYZ(3)),
  511.      1   (MX,LIMIT(1)),(FMX,FLIM(1))
  512. C       END CDE
  513. C
  514. C       LOCAL CDE
  515.         REAL*4 AU(3),AV(3),AW(3)
  516. C       HANDEDNESS PARAMETER, -1 FOR LEFT-HANDED USUALLY
  517.         DATA EPSLON/-1.0/
  518. C
  519.         S = 0.0
  520.         DO 1 J = 1,3
  521.         AV(J) = 0.0
  522.         AW(J) = 0.0
  523.         AU(J) = CAMWKG(J+3)-CAMWKG(J)
  524. 1       S = S + AU(J)**2
  525.         S = SQRT(S)
  526.         DO 2 J = 1,3
  527. 2       AU(J) = AU(J)/S
  528.         SIGMA = SQRT(AU(1)**2 + AU(2)**2)
  529. C       PREPARE LOOKING STRAIGHT UP OR DOWN
  530.         AV(1) = 1.0
  531.         AW(2) = -EPSLON
  532.         IF(AU(3) .GT. 0.0) AW(2) = -AW(2)
  533.         IF(SIGMA .LT. 1.0E-3) GO TO 4
  534. C       X AXIS
  535.         AV(1) = AU(2)/SIGMA
  536.         AV(2) = -AU(1)/SIGMA
  537.         AV(3) = 0.0
  538. C       Y AXIS
  539.         AW(1) = EPSLON*AU(1)*AU(3)/SIGMA
  540.         AW(2) = EPSLON*AU(2)*AU(3)/SIGMA
  541.         AW(3) = -EPSLON*SIGMA
  542. C       TRANSFER AXIS DIRECTION COSINES TO ROTATION MATRIX ROWS
  543. 4       DO 3 J = 1,3
  544.         AMTX(1,J) = AV(J)
  545.         AMTX(2,J) = AW(J)
  546. 3       AMTX(3,J) = AU(J)
  547.         RETURN
  548.         END
  549.         SUBROUTINE DRAWPQ(Z,IZDIM1)
  550.     IMPLICIT NONE
  551. C       DRAW VISIBLE PART OF SEGMENT PC-QC
  552. C
  553.     INTEGER IZDIM1
  554.         REAL*4 Z(IZDIM1,2)
  555. C
  556. C       COMMON STORAGE DESCRIPTOR
  557.  
  558.     INCLUDE DIGLIB$KOM:PLTCLP.PRM
  559.     REAL*4 ZMIN,ZMAX,AXISR(2),CAMXYZ(3)
  560.     REAL*4CAMWKG(6),XORG(3),GX(3),FX(2),CENTER(2),AMTX(3,3)
  561.     REAL*4 PLTORG(2),U,V,W
  562.     REAL*4 PLOTX,PLOTY,MX,NY,FMX,FNY,ZORG,PQLMT,FOCALL
  563.     INTEGER KSCALE
  564.         COMMON/COMDP/ZMIN,ZMAX,AXISR,PLOTX,
  565.      1   PLOTY,PLTORG,CAMXYZ,MX,NY,FMX,FNY,CAMWKG,XORG,
  566.      2   GX,FX,KSCALE,ZORG,CENTER,PQLMT,
  567.      3   AMTX,FOCALL
  568.         INTEGER LIMIT(2)
  569.     REAL*4 FLIM(2)
  570.         EQUIVALENCE(U,CAMXYZ(1)),(V,CAMXYZ(2)),(W,CAMXYZ(3)),
  571.      1   (MX,LIMIT(1)),(FMX,FLIM(1))
  572. C       END CDE
  573. C
  574. C
  575. C       CDE PACKAGE FOR DRAW3D,DRAWPQ
  576.     REAL*4 PC(3),QC(3),P(3),Q(3),ENDA(6),ENDB(6),OLDQ(3)
  577.     REAL*4 PW(3),QW(3),T(6),PK(3),QK(3)
  578.         INTEGER PHIP,PHIQ,PHIA,IBEAM,ICOLOR
  579.  
  580.         COMMON/COMDPA/PC,QC,P,Q,ENDA,ENDB,OLDQ,
  581.      1   PW,QW,T,PK,QK,PHIP,PHIQ,PHIA,IBEAM,ICOLOR
  582.  
  583. C       END OF CDE PACKAGE
  584. C
  585.     INTEGER KGOTO,JGOTO,KFLAG,MFLAG,IVIS
  586.     REAL*4 SL
  587.  
  588.         P(1) = PC(1)
  589.         P(2) = PC(2)
  590.         P(3) = PC(3)
  591.         Q(1) = QC(1)
  592.         Q(2) = QC(2)
  593.         Q(3) = QC(3)
  594. C       TEST IF P VISIBLE
  595. 2       IF(PHIP .EQ. 0) GO TO 30
  596. C       YES, TEST Q
  597. 7       IF(PHIP*PHIQ)10,4,3
  598. C       BOTH VISIBLE   SEGMENT DRAWABLE, PLOT   EXIT
  599. 3       KGOTO = 0
  600.         GO TO 300
  601. C       Q IS INVISIBLE, FIND LAST VISIBLE POINT ON SEGMENT PQ
  602. 4       JGOTO = 1
  603.         GO TO 200
  604. C       GIVE UP IF NOT FOUND IN MAXCUT1 BISECTIONS
  605. 5       IF(KFLAG .NE. 0) GO TO 6
  606. C       NEXT POINT
  607.         IBEAM = 0
  608.         RETURN
  609. C       POINT FOUND
  610. 6       Q(1) = ENDA(1)
  611.         Q(2) = ENDA(2)
  612.         Q(3) = ENDA(3)
  613.         GO TO 3
  614. C
  615. C       GAP IN SEGMENT, FIND LAST POINT TO CONNECT P.
  616. 10      JGOTO = 2
  617.         GO TO 200
  618. C       IF NOT FOUND (CANNOT FIND POINT WITH SAME VISIBILITY FN). TRY 2ND
  619. 11      IF(KFLAG .EQ. 0) GO TO 15
  620. C       SAVE OLD Q, RESET POINT   PLOT THIS PIECE.
  621.         OLDQ(1) = Q(1)
  622.         OLDQ(2) = Q(2)
  623.         OLDQ(3) = Q(3)
  624.         Q(1) = ENDA(1)
  625.         Q(2) = ENDA(2)
  626.         Q(3) = ENDA(3)
  627. C       DRAW FIRST PART OF SEGMENT AND COME BACK HERE
  628.         KGOTO = 2
  629.         GO TO 300
  630. C       RESTORE Q   FIND LOWER LIMIT OF UPPER SEGMENT.
  631. C       LIMITS FOR SEARCH
  632. 12      P(1) = Q(1)
  633.         P(2) = Q(2)
  634.         P(3) = Q(3)
  635.         Q(1) = OLDQ(1)
  636.         Q(2) = OLDQ(2)
  637.         Q(3) = OLDQ(3)
  638. C       BEAM OFF FIRST
  639. 15      IBEAM = 0
  640.         JGOTO = 3
  641.         GO TO 201
  642. C       IF SEGMENT TOO SHORT, GIVE UP.
  643. 13      IF(KFLAG .EQ. 0) GO TO 50
  644. C       LOWER END NOW NEWLY FOUND POINT.
  645. 14      P(1) = ENDA(1)
  646.         P(2) = ENDA(2)
  647.         P(3) = ENDA(3)
  648.         GO TO 3
  649. C       P INVISIBLE, CHECK Q. IF INVISIBLE, ADVANCE.
  650. 30      IBEAM = 0
  651.         IF(PHIQ .EQ. 0) GO TO 50
  652. C       FIND P
  653.         JGOTO = 4
  654.         GO TO 201
  655. C       IF NO POINT, GIVE UP.
  656. 31      IF(KFLAG) 14,50,14
  657. C
  658. C
  659. C       P VISIBLE, Q INVISIBLE, FIND Q.
  660. C       ENDB = INVISIBLE END OF INTERVAL, ENDA = VISIBLE
  661. 200     ENDB(1) = Q(1)
  662.         ENDB(2) = Q(2)
  663.         ENDB(3) = Q(3)
  664.         ENDA(1) = P(1)
  665.         ENDA(2) = P(2)
  666.         ENDA(3) = P(3)
  667. C       REQUIRED IVIS FUNCTION
  668. C       IN CASE OF GAP IN SEGMENT, CONSIDER POINT VISIBLE IF ITS VISIB.
  669. C       FUNCTION MATCHES THIS ONE AND UPDATE ENDA, ELSE ENDB.
  670.         PHIA = PHIP
  671.         GO TO 205
  672. C       P INVISIBLE, Q VISIBLE. FIND P.
  673. 201     ENDB(1) = P(1)
  674.         ENDB(2) = P(2)
  675.         ENDB(3) = P(3)
  676.         ENDA(1) = Q(1)
  677.         ENDA(2) = Q(2)
  678.         ENDA(3) = Q(3)
  679.         PHIA = PHIQ
  680. 205     KFLAG = 0
  681. C       GET PROJECTED LENGTH OF SEGMENT
  682.         PK(1) = XMIN + (ENDA(1)-1.0)*GX(1) - CAMWKG(1)
  683.         PK(2) = YMIN + (ENDA(2)-1.0)*GX(2) - CAMWKG(2)
  684.         PK(3) = ENDA(3)*GX(3) + ZORG - CAMWKG(3)
  685.         CALL ROTATE(PK,AMTX,ENDA(4))
  686.         PK(1) = XMIN + (ENDB(1)-1.0)*GX(1) - CAMWKG(1)
  687.         PK(2) = YMIN + (ENDB(2)-1.0)*GX(2) - CAMWKG(2)
  688.         PK(3) = ENDB(3)*GX(3) + ZORG - CAMWKG(3)
  689.         CALL ROTATE(PK,AMTX,ENDB(4))
  690. C       NEXT STEP
  691. 210     T(1) = (ENDA(1)+ENDB(1))/2.0
  692.         T(2) = (ENDA(2)+ENDB(2))/2.0
  693.         T(3) = (ENDA(3)+ENDB(3))/2.0
  694.         T(4) = (ENDA(4)+ENDB(4))/2.0
  695.         T(5) = (ENDA(5)+ENDB(5))/2.0
  696.         T(6) = (ENDA(6)+ENDB(6))/2.0
  697.         MFLAG = IVIS(T(1),T(2),T(3),Z,IZDIM1)
  698.         IF(MFLAG .EQ. PHIA) GO TO 220
  699. C       NOT VISIBLE, RESET INVISIBLE END.
  700.         ENDB(1) = T(1)
  701.         ENDB(2) = T(2)
  702.         ENDB(3) = T(3)
  703.         ENDB(4) = T(4)
  704.         ENDB(5) = T(5)
  705.         ENDB(6) = T(6)
  706. C       CHECK SEGMENT LENGTH (USE MAX OF X, Y DIFFERENCES)
  707. 216     SL = FOCALL*AMAX1(ABS(ENDA(4)/ENDA(6)-ENDB(4)/ENDB(6)),
  708.      1    ABS(ENDA(5)/ENDA(6)-ENDB(5)/ENDB(6)))
  709.         IF(SL .GE. PQLMT) GO TO 210
  710.         GO TO (5,11,13,31), JGOTO
  711. C       RECORD VISIBLE, UPDATE ENDA
  712. 220     KFLAG = MFLAG
  713.         ENDA(1) = T(1)
  714.         ENDA(2) = T(2)
  715.         ENDA(3) = T(3)
  716.         ENDA(4) = T(4)
  717.         ENDA(5) = T(5)
  718.         ENDA(6) = T(6)
  719.         GO TO 216
  720. C
  721. C
  722. C       DRAW P TO Q
  723. C
  724. C       IF BEAM IS ON, JUST MOVE IT TO Q.
  725. 300     IF(IBEAM .GT. 0) GO TO 310
  726. C       MOVE TO P, BEAM OFF.
  727.         PK(1) = XMIN + (P(1)-1.0)*GX(1) - CAMWKG(1)
  728.         PK(2) = YMIN + (P(2)-1.0)*GX(2) - CAMWKG(2)
  729.         PK(3) = P(3)*GX(3) + ZORG - CAMWKG(3)
  730.         CALL ROTATE(PK,AMTX,PW)
  731.         PW(1) = (PW(1)/PW(3)-XORG(1))*FOCALL + PLTORG(1) + CENTER(1)
  732.         PW(2) = (PW(2)/PW(3)-XORG(2))*FOCALL + PLTORG(2) + CENTER(2)
  733.         CALL GSMOVE(PW(1),PW(2))
  734. C       MOVE TO Q, BEAM ON. BEAM IS LEFT AND AT POINT Q.
  735. 310     QK(1) = XMIN + (Q(1)-1.0)*GX(1) - CAMWKG(1)
  736.         QK(2) = YMIN + (Q(2)-1.0)*GX(2) - CAMWKG(2)
  737.         QK(3) = Q(3)*GX(3) + ZORG - CAMWKG(3)
  738.         CALL ROTATE(QK,AMTX,QW)
  739.         QW(1) = (QW(1)/QW(3)-XORG(1))*FOCALL + PLTORG(1) + CENTER(1)
  740.         QW(2) = (QW(2)/QW(3)-XORG(2))*FOCALL + PLTORG(2) + CENTER(2)
  741.         CALL GSDRAW(QW(1),QW(2))
  742.         IBEAM = 1
  743.         IF(KGOTO .NE. 0) GO TO 12
  744. C
  745. 50      RETURN
  746.         END
  747.         SUBROUTINE DRAW3D(Z,IZDIM1,IZ,KX)
  748.     IMPLICIT NONE
  749. C       DRAW PLOT
  750. C
  751.     INTEGER IZDIM1
  752.         REAL*4 Z(IZDIM1,2)
  753.         CHARACTER*1 IZ(KX,2)
  754. C
  755. C       COMMON STORAGE DESCRIPTOR
  756.     INCLUDE DIGLIB$KOM:PLTCLP.PRM
  757.     REAL*4 ZMIN,ZMAX,AXISR(2),CAMXYZ(3)
  758.     REAL*4CAMWKG(6),XORG(3),GX(3),FX(2),CENTER(2),AMTX(3,3)
  759.     REAL*4 PLTORG(2),U,V,W
  760.     REAL*4 PLOTX,PLOTY,MX,NY,FMX,FNY,ZORG,PQLMT,FOCALL
  761.     INTEGER KSCALE
  762.         COMMON/COMDP/ZMIN,ZMAX,AXISR,PLOTX,
  763.      1   PLOTY,PLTORG,CAMXYZ,MX,NY,FMX,FNY,CAMWKG,XORG,
  764.      2   GX,FX,KSCALE,ZORG,CENTER,PQLMT,
  765.      3   AMTX,FOCALL
  766.         INTEGER LIMIT(2)
  767.     REAL*4 FLIM(2)
  768.         EQUIVALENCE(U,CAMXYZ(1)),(V,CAMXYZ(2)),(W,CAMXYZ(3)),
  769.      1   (MX,LIMIT(1)),(FMX,FLIM(1))
  770. C       END CDE
  771. C
  772. C
  773. C       CDE PACKAGE FOR DRAW3D,DRAWPQ
  774.     REAL*4 PC(3),QC(3),P(3),Q(3),ENDA(6),ENDB(6),OLDQ(3)
  775.     REAL*4 PW(3),QW(3),T(6),PK(3),QK(3)
  776.         INTEGER PHIP,PHIQ,PHIA,IBEAM,ICOLOR
  777.  
  778.         COMMON/COMDPA/PC,QC,P,Q,ENDA,ENDB,OLDQ,
  779.      1   PW,QW,T,PK,QK,PHIP,PHIQ,PHIA,IBEAM,ICOLOR
  780.  
  781.     INTEGER KSCAN,KFIX,JPC,KPC,JQC,KQC
  782.     REAL*4 DELSCN,DELFIX
  783. C       END OF CDE PACKAGE
  784. C
  785. C       SAVE Z DIMENSION IN COMMON TO PASS ALONG THROUGH DRAWPQ TO IVIS
  786. C       SCAN ALONG X FIRST AT CONSTANT Y
  787. C
  788. C       INDEX OF COORDINATE BEING STEPPED ALONG A LINE
  789.         KSCAN = 1
  790. C       INDEX OF COORDINATE BEING HELD FIXED
  791.         KFIX = 2
  792. C       SET FIXED COORDINATE   INCREMENT
  793.         PC(KFIX) = 1.0
  794.         DELFIX = 1.0
  795. C       SET ROVING COORDINATE   INCREMENT INITIALLY
  796.         DELSCN = 1.0
  797.         QC(KSCAN) = 1.0
  798. C       BEGIN SCANNING A LINE
  799. 101     QC(KFIX) = PC(KFIX)
  800.         IBEAM = 0
  801. C       NEXT POINT IN LINE SCAN
  802. 102     PC(KSCAN) = QC(KSCAN)
  803.         QC(KSCAN) = PC(KSCAN) + DELSCN
  804. C       WORKING INDICES
  805.         JPC = IFIX(PC(1))
  806.         KPC = IFIX(PC(2))
  807.         JQC = IFIX(QC(1))
  808.         KQC = IFIX(QC(2))
  809. C       PHI FUNCTIONS
  810.         PC(3)=Z(JPC,KPC)
  811.         QC(3)=Z(JQC,KQC)
  812.         PHIP=ICHAR(IZ(JPC,KPC))-1
  813.         PHIQ=ICHAR(IZ(JQC,KQC))-1
  814. 200     CALL DRAWPQ(Z,IZDIM1)
  815. C       TEST IF LINE IS DONE
  816.         IF((QC(KSCAN)-1.0)*(QC(KSCAN)-FLIM(KSCAN)) .LT. 0.0) GO TO 102
  817. C       LINE DONE. ADVANCE FIXED COORDINATE.
  818.         PC(KFIX) = PC(KFIX) + DELFIX
  819. C       TEST IF FIXED COORDINATE NOW OFF LIMITS
  820.         IF((PC(KFIX)-1.0)*(PC(KFIX)-FLIM(KFIX)) .GT. 0.0) GO TO 55
  821. C       FLIP INCREMENT. SCAN BEGINS AT QC OF PREVIOUS LINE.
  822.         DELSCN = -DELSCN
  823.         GO TO 101
  824. C       TEST IF WE HAVE DONE Y SCAN YET.
  825. 55      IF(KSCAN .EQ. 2) RETURN
  826. C       NO, SCAN Y DIRECTION AT FIXED X.
  827.         KSCAN = 2
  828.         KFIX = 1
  829. C       START FIXED X AT X OF LAST TRAVERSE
  830.         PC(1) = QC(1)
  831. C       THEN STEP X IN OPPOSITE DIRECTION
  832.         DELFIX = -DELSCN
  833. C       WE ENDED UP AT MAX. Y, SO FIRST Y SCAN GOES BACKWARDS
  834.         DELSCN = -1.0
  835. C       INITIAL Y FOR FIRST LINE
  836.         QC(2) = FNY
  837.         GO TO 101
  838.         END
  839.         FUNCTION IVIS(XI,ETA,ZETA,Z,IZDIM1)
  840. C                  CORRECTED VERSION, 24FEB69
  841. C       DETERMINE IF POINT XI, ETA IS VISIBLE
  842. C       POINT IS GIVEN BY XI, ETA, ZIN
  843. C       AND VISIBILITY IS TESTED WITH RESPECT TO SURFACE Z(X,Y)
  844. C        XI, ETA COORDINATES EXPRESSED AS INDICES OF ARRAY Z, BUT NEED NOT
  845. C       BE INTEGERS IN GENERAL. FOR ENTRY IVIS, THEY MUST BE.
  846. C
  847.         DIMENSION Z(IZDIM1,2)
  848. C
  849. C       COMMON STORAGE DESCRIPTOR
  850.     COMMON/PLTCLP/XMIN,XMAX,YMIN,YMAX
  851.         COMMON/COMDP/ZMIN,ZMAX,AXISR(2),PLOTX,
  852.      1   PLOTY,PLTORG(2),CAMXYZ(3),MX,NY,FMX,FNY,CAMWKG(6),XORG(3),
  853.      2   GX(3),FX(2),KSCALE,ZORG,CENTER(2),PQLMT,
  854.      3   AMTX(3,3),FOCALL
  855.         DIMENSION LIMIT(2),FLIM(2)
  856.         EQUIVALENCE(U,CAMXYZ(1)),(V,CAMXYZ(2)),(W,CAMXYZ(3)),
  857.      1   (MX,LIMIT(1)),(FMX,FLIM(1))
  858. C       END CDE
  859. C
  860.         LOGICAL LSOLID
  861.         COMMON /COMDP1/ LSOLID
  862.         EQUIVALENCE (CX,CY), (DXI,DETA), (XIW,ETAW),
  863.      1  (XIEND,ETAEND), (KDXI,KDETA), (KXIEND,KETEND),
  864.      2  (DX,DY)
  865. C
  866. C
  867. C
  868. C       INITIAL P FUNCTION
  869. 5       IVIS = 0
  870.         R = U-XI
  871.         S = V-ETA
  872.         T = W-ZETA
  873. C       TEST IF WE CHECK ALONG X
  874.         IF(ABS(R) .LT. 1.0) GO TO 20
  875. C       CONSTANTS FOR Y(X),Z(X)
  876.         CY = S/R
  877.         CZ = T/R
  878.         DXI = SIGN(1.0,R)
  879. C       INITIAL POINT. TAKE AINT(XI) IF .NE. XI AND STEPS IN RIGHT DIRECTI
  880.         XIW = AINT(XI)
  881.         IF((XIW-XI)*DXI .LE. 0.0) XIW = XIW+DXI
  882. C       SKIP IF OFF LIMITS (WE ARE ON EDGE OF PLOT REGION)
  883.         IF((XIW-1.0)*(XIW-FMX) .GT. 0.0) GO TO 20
  884. C       FINAL POINT. TAKE AINT(U) IF IT MOVES OPPOSITE DXI, ELSE ROUND
  885.         XIEND = AINT(U)
  886.         IF((XIEND-U)*DXI .GE. 0.0) XIEND = XIEND-DXI
  887. C       BUT DO NOT GO BEYOND EDGES
  888.         XIEND = AMAX1(1.0,AMIN1(XIEND,FMX))
  889. C
  890. C                AFTER TESTING, RE-PRDER THESE STATEMENTS
  891.         J = IFIX(XIW)
  892.         KDXI = IFIX(DXI)
  893.         KXIEND = IFIX(XIEND)
  894.         XW = XIW-U
  895. C
  896. C       IF LIMITS CROSS, NO TEST
  897.         IF((XIEND-XIW)*DXI .LE. 0.0) GO TO 20
  898. C       GET Y(X)
  899. 3       YW = V + XW*CY
  900. C       IF Y IS OFF LIMITS, DONE
  901.         IF((YW-1.0)*(YW-FNY)) 21,25,20
  902. C       ON EDGE EXACTLY, NO INTERPOLATION
  903. 25      K = IFIX(YW)
  904.         IF(W + XW*CZ - Z(J,K)) 4,10,7
  905. C       INDEX FOR LOWER Y OF INTERVAL
  906. 21      K = IFIX(YW)
  907.         DY = YW-FLOAT(K)
  908. C       TEST Z OF LINE - Z OF SURFACE. ACCEPT ZERO DIFFERENCE.
  909.         IF((W + XW*CZ)-(Z(J,K) + DY*(Z(J,K+1)-Z(J,K)))) 4,10,7
  910. C       NEGATIVE. OK IF IVIS NEG. OR ZERO, ELSE REJECT
  911. 4       IF(IVIS) 10,6,40
  912. C       IVIS WAS ZERO, SET NEG.
  913. 6       IVIS = -1
  914.         GO TO 10
  915. C       PLUS. OK IF IVIS + OR ZERO, ELSE, REJECT
  916. 7       IF(IVIS) 40,8,10
  917. C       SET PLUS
  918. 8       IVIS = 1
  919. C       TEST IF DONE. ADVANCE IF NOT
  920. 10      IF(J .EQ. KXIEND) GO TO 20
  921.         J = J+KDXI
  922.         XW = XW+DXI
  923.         GO TO 3
  924. C
  925. C       CHECK IF WE TEST IN Y DIRECTION
  926. 20      IF(ABS(S) .LT. 1.0) GO TO 45
  927. C       CONSTANTS FOR X(Y),Z(Y)
  928.         CX = R/S
  929.         CZ = T/S
  930.         DETA = SIGN(1.0,S)
  931.         ETAW = AINT(ETA)
  932.         IF((ETAW-ETA)*DETA .LE. 0.0) ETAW = ETAW+DETA
  933. C       CHECK WHETHER ON LIMITS
  934.         IF((ETAW-1.0)*(ETAW-FNY) .GT. 0.0) GO TO 45
  935.         ETAEND = AINT(V)
  936.         IF((ETAEND-V)*DETA .GE. 0.0) ETAEND = ETAEND-DETA
  937.         ETAEND = AMAX1(1.0,AMIN1(FNY,ETAEND))
  938.         K = IFIX(ETAW)
  939.         KDETA = IFIX(DETA)
  940.         YW = ETAW-V
  941.         KETEND = IFIX(ETAEND)
  942. C       IF LIMITS CROSS, NO TEST, BUT TEST SINGLE POINT IF WE HAVE ALREADY
  943. C       TESTED X
  944.         A = ETAEND-ETAW
  945.         IF(A*DETA .LT. 0.0) GO TO 45
  946.         IF(A .EQ. 0.0 .AND. IVIS .EQ. 0) GO TO 45
  947. C       GET X(Y)
  948. 23      XW = U + YW*CX
  949. C       IF X OFF LIMITS, DONE
  950.         IF((XW-1.0)*(XW-FMX)) 44,46,45
  951. 46      J = IFIX(XW)
  952.         IF(W + YW*CZ - Z(J,K)) 24,30,27
  953. 44      J = IFIX(XW)
  954.         DX = XW-FLOAT(J)
  955.         IF((W + YW*CZ) - (Z(J,K)+DX*(Z(J+1,K)-Z(J,K)))) 24,30,27
  956. C       NEG., IVIS MUST BE NEG OR ZERO ELSE REJCT
  957. 24      IF(IVIS) 30,26,40
  958. C       SET IVIS NEG
  959. 26      IVIS = -1
  960.         GO TO 30
  961. C       POS, IVIS MUST BE ZERO OR + ELSE REJECT
  962. 27      IF(IVIS) 40,28,30
  963. 28      IVIS = 1
  964. C       TEST IF DONE, ADVANCE IF NOT.
  965. 30      IF(K .EQ. KETEND) GO TO 45
  966.         K = K+KDETA
  967.         YW = YW+DETA
  968.         GO TO 23
  969. C
  970. C       REJECT THIS POINT, RETURN ZERO.
  971. 40      IVIS = 0
  972.         RETURN
  973. C
  974. C       ACCEPT. RETURN +/- 1
  975. C       IF IVIS ZERO, CAMERA WAS RIGHT OVER XI, ETA.
  976. 45      IF(IVIS .EQ. 0) IVIS = ISIGN(1,IFIX(T))
  977.         IF (LSOLID .AND. (IVIS .EQ. -1)) GO TO 40
  978.         RETURN
  979.         END
  980.         SUBROUTINE ROTATE(XIN,A,XOUT)
  981.     IMPLICIT NONE
  982. C       ROTATE VECTOR XIN BY MATRIX A TO GET XOUT
  983. C
  984. C
  985.         REAL*4 XIN(3),A(9),XOUT(3)
  986.         XOUT(1) = A(1)*XIN(1) + A(4)*XIN(2) + A(7)*XIN(3)
  987.         XOUT(2) = A(2)*XIN(1) + A(5)*XIN(2) + A(8)*XIN(3)
  988.         XOUT(3) = A(3)*XIN(1) + A(6)*XIN(2) + A(9)*XIN(3)
  989.         RETURN
  990.         END
  991.  
  992.